#!/usr/bin/env python

# Greg Johnston
#  <greg.johnston@gmail.com>
#  control.py
#  The RitualController class forms the "Controller" part of our MVC form

#### TODO ####
# Don't only use GTK things for the file prompt
# Can't only pass things as a log, because it won't be modified correctly
##############

import os
from entry import RitualEntry
from log import RitualLog
from coolrunning import CoolRunningLog
from config import RitualConfig
from calc import *

class RitualController:
	"""Control the View classes (GTKView, etc.) and provide essential functions"""
	EditorMode = 0
	BlankEntry = RitualEntry("", 0, 0, 5025, "", "")
	Config = None

	def __init__(self):#, viewtype):
		# Load config
		self.Config = RitualConfig()
		self.CurrentFile = self.Config.config["default_file"]

		self.Log = RitualLog()
		try:
			self.Log.read_file(self.Config.config["default_file"])
		except IOError:
			open(self.Config.config["default_file"], "w").close() # Create a blank file

		self.View = self.Config.get_view()
#		from wxview import wxView
#		self.View = wxView()

		# Setup the View
		self.View.connect(self.handlers())
		self.View.calendar_mark_month(self.Log)
		self.View.show_curve(self.Log)
		self.View.title(self.CurrentFile)

	## Handlers
	def handlers(self):
		"""Returns a dict of the handler functions for all our signals"""
		return { "on_menunew_activate" : self.new,
				 "on_menuconvert_activate" : self.convert,
				 "on_menuopen_activate" : self.open,
				 "on_menusave_activate" : self.save,
				 "on_menusaveas_activate" : self.save_as,
				 "on_menuexit_activate" : self.exit,
				 "on_menuabout_activate" : self.View.show_about,
				 "on_calendar_day_selected_double_click" : self.show_editor,
				 "on_calendar_day_selected" : self.show_run_data,
				 "on_editor_close" : self.View.hide_editor,
				 "on_editorcalc_clicked" : self.View.time_calc_set,
				 "on_calc_add" : self.View.calc_add,
				 "on_courseentry_changed" : self.courseentry_changed,
				 "on_editor_submit" : self.submit,
				 "on_date_today" : self.View.date_today,
				 "on_update_pace" : self.View.update_pace,
				 "remark_calendar" : self.calendar_change,
				 "on_previous_clicked" : self.reader_backward,
				 "on_next_clicked" : self.reader_forward,
				 "on_edit_clicked" : self.edit_run,
				 "on_delete_clicked" : self.delete_run }

	## Calendar
	def calendar_change(self, signal):
		"""Clears the marked days on the calendar. Remarks the days which are in this month."""
		self.View.clear_calendar()
		self.View.calendar_mark_month(self.Log)

	## Viewer
	def reader_backward(self, button):
		"""Moves the reader back one run"""
		self.View.reader_move(-1, self.Log)

	def reader_forward(self, button):
		"""Moves the reader forward one run"""
		self.View.reader_move(1, self.Log)

	def show_run_data(self, calendar):
		"""Boilerplate for View's show_run_data, passes log to it"""
		self.View.show_run_data(calendar, self.Log)

	## Editor controllers
	def show_editor(self, widget):
		"""Shows the Editor window"""
		self.EditorMode = 0 # Add
		self.View.set_combos(self.Log)
		self.View.show_editor(self.BlankEntry)

	def edit_run(self, widget):
		"""Edits the currently-selected run"""
		self.EditorMode = 1 # Edit
		sdate = self.View.calendar_selected_date()
		run = self.Log.log[(sdate, self.View.ViewerOffset)]
		self.View.set_combos(self.Log)	
		self.View.show_editor(run)

	def delete_run(self, widget):
		"""Deletes the currently-selected run"""
		sdate = self.View.calendar_selected_date()
		self.Log.log = self.Log.remove_entry(sdate, self.View.ViewerOffset)
		self.View.set_saved(False, self.CurrentFile)
		self.show_run_data(self.View.Calendar)

	def submit(self, widget):
		"""Submits the form values in the editor to a log entry"""
		date = string_date(self.View.get_value("date"))
		offset = self.View.ViewerOffset
		print "Editor Mode: ", self.EditorMode
		if self.EditorMode == 1: # Edit Mode
			self.Log.log = self.Log.remove_entry(date, offset)
		self.Log.add_entry(date,
							escape(self.View.get_value("course")),
							float(self.View.get_value("distance")),
							self.View.get_value("distanceunit"),
							time_in_seconds(self.View.get_value("time")),
							escape(self.View.get_value("shoes")),
							escape(self.View.get_value("notes")),
							offset=offset)
		self.View.set_saved(False, self.CurrentFile)
		self.View.hide_editor()
		self.View.calendar_mark_month(self.Log)
		self.View.show_curve(self.Log)
		self.show_run_data(self.View.Calendar)

	def courseentry_changed(self, widget):
		"""Updates the distance and unit based on the courseentry"""
		self.View.set_distance_from_course(self.Log.courses)

	## Convert/Import/IO/Menu Functions
	def exit(self, widget=None):
		"""Exits the log, making sure to save first"""
		status = self.View.checksave()
		if status == "save":
			self.save()
			self.View.quit()
		elif status == "quit" or status == True:
			self.View.quit()
		elif status == "cancel":
			pass
		else:
			print status

	def new(self, widget=None):
		"""Saves current log and creates a new one"""
		self.View.checksave()
		self.CurrentFile = None
		self.log = {}
		self.courses = {}
		self.View.calendar_mark_month(self.Log)
		self.View.show_curve(self.Log)
		self.View.title(self.CurrentFile)
		self.View.set_saved(False, self.CurrentFile)

	def open(self, widget=None):
		"""Selects a file to open and opens it"""
		filename = self.View.fileprompt("open")
		self.open_file(filename)

	def open_file(self, filename):
		"""Opens a file, given its name"""
		self.Log.read_file(filename)
		self.Config.config["default_file"] = filename
		self.Config.save_config()
		self.CurrentFile = filename
		self.View.calendar_mark_month(self.Log)
		self.View.show_curve(self.Log)
		self.View.title(self.CurrentFile)
		self.View.set_saved(True, self.CurrentFile)

	def convert(self, widget=None):
		"""Imports a Coolrunning-formatted log"""
		filename = self.View.fileprompt("convert")
		crlog = CoolRunningLog(filename)
		merged = merge_logs(self.Log, crlog)
		self.Log.courses = merged[0]
		self.Log.log = merged[1]
		self.View.set_saved(False, self.CurrentFile)

	def save_as(self, widget=None):
		"""Saves the currently open file to a new file"""
		filename = self.View.fileprompt("saveas")
		self.CurrentFile = filename
		self.save(widget)
		self.View.title(self.CurrentFile)

	def save(self, widget=None):
		"""Saves the currently open file"""
		if self.CurrentFile and self.CurrentFile != "":
			self.Log.save_file(self.CurrentFile)
			self.View.set_saved(True, self.CurrentFile)
		else:
			self.save_as(widget)

if __name__ == "__main__":
	controller = RitualController()

	if len(os.sys.argv) > 1: # always 1, for script name
		controller.open_file(os.sys.argv[1])

	controller.View.show_today_run_data(controller.Log)
	controller.View.run()

	
